package com.wlper.lib.view.loading;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.FrameLayout;

/**
 * 最基础的加载机制，包含了对加载状态的逻辑控制。 加载动画和一些加载状态（如加载失败、重新加载）的界面显示效果以及界面事件添加，
 * 需要通过复写onStartLoading()和onStopLoading(boolean)方法来实现。
 * 
 * @author wanliang527
 * @date 2014-06-12
 * 
 * 
 */
public abstract class BaseLoadLayout extends FrameLayout {

    private LoadStateHandler mStateHandler; // 加载状态处理器
    private boolean isLoading;// 当前是否处在加载状态

    protected Context mContext;
    protected LayoutInflater mInflater;

    public BaseLoadLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    public BaseLoadLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public BaseLoadLayout(Context context) {
        super(context);
        init(context);
    }

    /**
     * 初始化操作。对一些对象进行实例化，方便子类使用。
     * 
     * @param context
     */
    protected void init(Context context) {
        mContext = context;
        mInflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    /**
     * 该方法用于子类复写。 开始加载的界面效果的初始化，包括清除加载失败界面、添加加载界面、设置加载动画
     */
    protected abstract void startLoading();

    /**
     * 该方法用于子类复写。 结束加载的一些操作。根据加载结果来做不同的操作。
     * 如果加载成功，清除加载界面、加载失败界面以及相关的一些动画，即将该控件恢复成原始Layout的样式；
     * 如果加载失败，清除加载界面以及相关的动画，显示加载失败界面；
     * 
     * @param isSuccess
     *            是否加载成功
     */
    protected abstract void stopLoading(boolean isSuccess);

    /**
     * 加载成功，但是没有数据的处理
     */
    public abstract void onNoData();

    /**
     * “正在加载中”。如果已经在加载，返回；否则设置加载状态标识为true，并调用startLoading()方法和外部处理接口中的onLoading(
     * )。
     * 
     * @return 该方法是否被成功调用
     */
    public boolean onLoading() {
        if (isLoading)
            return false;
        isLoading = true;
        startLoading();
        if (mStateHandler != null) {
            mStateHandler.onLoading();
        }
        return true;
    }

    /**
     * “加载成功”。如果没有处于加载状态，返回；否则设置加载状态标识为false，并调用stopLoading(true)
     * 方法和外部处理接口中的onLoadSuccess() 在stopLoading(true)方法中会清空加载相关的界面元素。
     * 
     * @return 该方法是否被成功调用
     */
    public boolean onLoadSuccess() {
        if (!isLoading)
            return false;
        isLoading = false;
        stopLoading(true);
        if (mStateHandler != null) {
            mStateHandler.onLoadSuccess();
        }
        return true;
    }

    /**
     * “加载失败”。如果没有处于加载状态，返回；否则设置加载状态标识为false，并调用stopLoading(false)
     * 方法和外部处理接口中的onLoadFailed() 在stopLoading(false)方法中会隐藏加载动画，显示加载失败界面。
     * 
     * @return 该方法是否被成功调用
     */
    public boolean onLoadFailed() {
        if (!isLoading)
            return false;
        isLoading = false;
        stopLoading(false);
        if (mStateHandler != null) {
            mStateHandler.onLoadFailed();
        }
        return true;
    }

    /**
     * “重新加载”。会调用onLoading()方法以及外部处理接口中的onReload()方法。
     * 注意：这里会调用两次外部处理接口的onLoading()方法。
     * 
     * @return 该方法是否被成功调用
     */
    public boolean onReload() {
        boolean b = onLoading();
        if (mStateHandler != null)
            mStateHandler.onReload();
        return b;
    }

    /**
     * 获取当前是否处于加载状态
     * 
     * @return
     */
    public boolean isLoading() {
        return isLoading;
    }

    /**
     * 设置是否处在加载状态
     * 
     * @param isLoading
     * @return 设置成功的话返回true，否则返回false
     */
    protected boolean setLoadingFlag(boolean isLoading) {
        boolean b = isLoading();
        if (b == isLoading) {
            return false;
        } else {
            this.isLoading = isLoading;
            return true;
        }
    }

    /**
     * 获取加载状态的处理器对象
     * 
     * @return
     */
    public LoadStateHandler getStateHandler() {
        return mStateHandler;
    }

    /**
     * 设置加载状态的处理器
     * 
     * @param stateHandler
     */
    public void setStateHandler(LoadStateHandler stateHandler) {
        this.mStateHandler = stateHandler;
    }

    /**
     * 加载状态处理器。该接口供外部在各个加载状态过程中添加一些事件。
     * 
     * @author wanliang527
     * 
     */
    public static interface LoadStateHandler {
        public void onLoading();

        public void onLoadFailed();

        public void onLoadSuccess();

        /**
         * 注意：重新加载会调用onLoading()，如果有设置onReload()事件，注意与onLoading()事件的区别，
         * 避免重复操作同一事件。
         */
        public void onReload();

    }

}
